/*
* 一个用于三维场景中的拾取类Pick.js
*
* Daniel
*
* 2018.02.28
*
*
* */
define(function(){
    
    var Pick = function(){
        this.scene = {};
        this.callback = function (){};
        this.objectArray = [];
        this.camera = {};
        this.pickEnable = true;         //用于控制拾取
        this.button = {
            winX:null,
            winY:null
        };          //用于鼠标事件分离
        this.multiplePick = false;          //用于调用多项选择
        this.contArray = {
            pickArray: [],
            oldColor: [],
            id: [],
            time: null,
            otherData: [],
            oneArray:[],
            oneOldColor:[]
    
        };              //一个拾取模型存储器
        this.contMoreArray = {
            pickArray: [],
            oldColor: [],
            id: [],
            time: null,
            otherData: [],
            oneArray:[],
            oneOldColor:[]
    
        };              //一个拾取模型存储器
        
        this.temporary = '';                //一个临时容器
        
        this.world = {};                    //依赖元素
    
    };
    
    //初始化参数列表
    Pick.prototype.init = function (World,objectArray) {
        this.world = World;
        this.scene = World.scene;
        this.sceneHelper = World.sceneHelper;
        this.scene.modelArray = [];
        this.objectArray = objectArray ||  World.modelArray;
        this.camera = World.camera;
        this.pickEnable = World.camera.pickEnable;
        //this.tranform = new THREE.TransformControls(this.camera,World.renderer.domElement);
        //this.sceneHelper.add(this.tranform);
        return this.pick(World,objectArray);
    };
    
    //拾取事件
    Pick.prototype.pick = function(){
        var scope = this;
        return function(event,callback,objectArray){
        if(scope.pickEnable == false)return;
        if (event) event.preventDefault();
        var raycaster = new THREE.Raycaster();
        var mouse = new THREE.Vector2();
        var pickArray;
        // mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        // mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;         //基于窗口
        mouse.x = (event.layerX / scope.world.changeSize.clientWidth) * 2 - 1;                  //基于视口
        mouse.y = -(event.layerY / scope.world.changeSize.clientHeight) * 2 + 1;
        
        objectArray !== undefined ? pickArray = objectArray : pickArray = scope.objectArray;
        raycaster.setFromCamera(mouse, scope.camera);
        var feedback = raycaster.intersectObjects(pickArray);
        if ( callback !== undefined) callback(feedback,scope);
            // scope.tranform.detach();
        if (feedback.length > 0){
            // scope.tranform.attach( feedback[0].object );
            return feedback
        }
     };
    };
    
    //鼠标位置监听器
    Pick.prototype.mouseMonitor = function (event,object){
        var returnObj;
        var flag = event.button;
        var wx = event.layerX;
        var wy = event.layerY;
        var wFx = object.winX;
        var wFy = object.winY;
        var offset = false;
        var eventFlag = wFx;
        if(eventFlag == null){
            object.winX = wx;
            object.winY = wy;
            return;
        }else{
            if( wFx == wx &&  wFy == wy)offset = true;
            object.winX = null;
            object.winY = null;
        }
        return  returnObj = {
            flag: flag,
            offset: offset
        }
        
    };
    
    //单项拾取
    Pick.prototype.uniterm = function(feedback,scope) {
        var contArray = scope.contArray;
        var scene = scope.sceneHelper;
        var reset = contArray.oneArray[0];
        if (feedback && feedback.length > 0)
        {
            var object = feedback[0].object;
            scope.showModelData(object);
        }
        else{
            scope.removeHit(reset,contArray,scene);
            
        }
    };
    
    //多项拾取
    Pick.prototype.multiple = function(objects,scope){
        if (objects.length > 0)
        {
            var contArray = scope.contArray;
            var object = objects[0].object;
            var oldColor = object.material.color;
            var id = object.id;
            if (contArray.id.indexOf(id)==-1)
            {
                contArray.pickArray.push(object);
                contArray.id.push(id);
                contArray.oldColor.push(oldColor);
                object.material.color = new THREE.Color();
                //showData(object, boolean.pick);
                var time = setInterval(function ()
                {
                    if (!this.multiplePick)
                    {
                        var len = contArray.pickArray.length;
                        if (len > 0)
                        {
                            for (var i = 0; i < len; i++)
                            {
                                var mesh = contArray.pickArray[i];
                                var color = contArray.oldColor[i];
                                mesh.material.color = color;
                            }
                            contArray.pickArray = [];
                            contArray.oldColor = [];
                            contArray.id = [];
                        }
                        clearInterval(time);
                    }
                }, 1000);
            
            }
        } else
        {
            console.warn("未获取到模型，请重新拾取……");
            return;
        }
    };
    
    //拾取颜色反馈（更改当前模型的色彩）
    Pick.prototype.showModelData = function (params,more){
        if(more!==undefined){
            this.moreModel(params);
            return;
        }else{
            this.oneModel(params);
            return;
        }
    };
    
    //单个物体高亮
    Pick.prototype.oneModel = function (params) {
        var contArray = this.contArray;
        var scene = this.sceneHelper;
        var reset = contArray.oneArray[0];
        var object = params;
        if (object !== undefined){
            var id = object.id;
            var flag = contArray.id.indexOf(id);
            if ( flag==-1 ){
                var oldColor = object.material.color;
                if(reset!==undefined){
                    this.removeHit(reset,contArray,scene);
                }
                contArray.id.push(id);
                contArray.oneArray.push(object);
                contArray.oneOldColor.push(oldColor);
                object.material.color = new THREE.Color(0x4285f4);
                object.material.needsUpdate = true;
                this.pickBorder(object,0x03ff47);
                this.temporary = object;                 //用于交互操作
                this.world.focusModel = object;
            }
        }
        else{
            this.removeHit(reset,contArray,scene);
        }
    };
    
    //高亮
    Pick.prototype.lightModel = function(params,flag){
        var object = params;
        if (object !== undefined){
                var id = object.name;
            if(flag){
                object.material.color = new THREE.Color(0xff0b36);
                object.material.needsUpdate = true;
            }else{
                var color = this.world.colorGroup[""+id+""].color;
                object.material.color = color;
                object.material.needsUpdate = true;
            }
        }
    };
    
    //移除单个选中状态
    Pick.prototype.removeHit = function(reset,contArray,scene) {
        if (reset !== undefined) {
            reset.material.color = contArray.oneOldColor[0];
            contArray.oneArray = [];
            contArray.oneOldColor = [];
            contArray.id = [];
            var borders = this.world.modelBoderGroup["pickBorders"];
            scene.remove(borders);
            this.temporary = undefined;
        }
    };
    
    //拾取边框反馈（添加边框）
    Pick.prototype.pickBorder = function(object,color){
        var box = new THREE.BoxHelper( object, color );
        var position = box.geometry.attributes.position;
        var points = position.array;
        var vectorArray = [];
        var groups = new THREE.Group();
        groups.name = "pickBorders";
        //groups.position.copy(object.position);
        var material = new THREE.LineBasicMaterial({
            color: color,         //mesh.material.color
            depthTest : false,
            transparent : true
        });
        var len = points.length;
        for(var i = 0; i<len;i+=3){
            var vectors = new THREE.Vector3(points[i],points[i+1],points[i+2]);
            vectorArray.push(vectors);
        }
        var vectorArrays = [
            [vectorArray[0], vectorArray[1]],
            [vectorArray[0], vectorArray[3]],
            [vectorArray[0], vectorArray[4]],
            [vectorArray[2], vectorArray[1]],
            [vectorArray[2], vectorArray[3]],
            [vectorArray[2], vectorArray[6]],
            [vectorArray[5], vectorArray[1]],
            [vectorArray[5], vectorArray[4]],
            [vectorArray[5], vectorArray[6]],
            [vectorArray[7], vectorArray[4]],
            [vectorArray[7], vectorArray[3]],
            [vectorArray[7], vectorArray[6]]
        ];
        var length = vectorArrays.length;
        for(var j = 0; j <length; j++){
            var geom = new THREE.Geometry();
            var end = vectorArrays[j][1];
            var start = vectorArrays[j][0];
            var X = Number(end.x - start.x);
            var Y = Number(end.y - start.y);
            var Z = Number(end.z - start.z);
            var maxLength = Math.max(Math.max(Math.abs(X),Math.abs(Y)),Math.abs(Z));
            var segments = maxLength/0.5;
            var deltX = X/segments;
            var deltY = Y/segments;
            var deltZ = Z/segments;
            var newPoint = new THREE.Vector3(vectorArrays[j][0].x,vectorArrays[j][0].y,vectorArrays[j][0].z);
            var long = Math.ceil(segments)+1;
            for( var k = 0; k < long; k++){
                if(k!=0){
                    if(k<segments){
                        newPoint.x += deltX;
                        newPoint.y += deltY;
                        newPoint.z += deltZ;
                        geom.vertices.push(newPoint.clone());
                    }else{
                        geom.vertices.push(end);
                    }
                }else{
                    geom.vertices.push(start);
                }
            }
            var borderlines = new THREE.LineSegments(geom, material);
            groups.add(borderlines);
        }
        this.world.modelBoderArray.push(groups);
        this.world.modelBoderGroup[""+groups.name+""]=groups;
        this.sceneHelper.add( groups );
    };
    
    //移除边框
    Pick.prototype.removePickBorder = function (){
        var array = this.world.modelBoderArray;
        if(array.length == 0)return;
        var len = array.length;
        for(var i = 0; i < len; i++){
            var line = array[i];
            this.scene.remove(line);
        }
    };
    
    //多功能拾取
    Pick.prototype.flexoPick = function (){
        var scope = this;
        return function(event){
            var flagss = scope.mouseMonitor(event,scope.button);
            if(flagss == undefined)return;
            if(flagss.flag == 0 && flagss.offset ){
                if (scope.multiplePick)
                {
                    scope.pick()(event, scope.multiple);
                } else
                {
                    scope.pick()(event, scope.uniterm);
//                    console.warn("多功能拾取，请摁下‘Ctrl’");
                }
            }
        };
    };
    
    return Pick;
    
});